package com.cs.manaer.service;

import com.cs.manaer.common.constant.ManagerConstant;
import com.cs.manaer.common.utils.RedisSerializableUtils;
import com.cs.manaer.controller.req.AppReleaseReqMsg;
import com.cs.manaer.controller.res.ListAppReleaseResMsg;
import com.cs.manaer.dao.AppReleaseMapper;
import com.cs.manaer.po.AppRelease;
import com.google.gson.Gson;
import com.lin.common.constant.CommonConstant;
import com.lin.common.constant.RedisConstant;
import com.lin.common.error.CustomRuntimeException;
import com.lin.common.error.ErrorCode;
import com.lin.common.utils.BeanCopyUtils;
import com.lin.common.utils.CustomFileUtils;
import com.lin.common.utils.DateUtils;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.io.IOException;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Component
public class AppReleaseServiceImpl implements AppReleaseService {
    private static final Logger log = LoggerFactory.getLogger(AppReleaseServiceImpl.class);
    @Value("${cs.prefix-path}")
    private String prefixPath;
    @Value("${cs.visit.url}")
    private String visitUrl;

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private AppReleaseMapper appReleaseMapper;

    /**
     * @param id      发布的ID
     * @param optFlag 1：发布，3暂停
     * @return
     * @throws CustomRuntimeException
     */
    @Transactional
    @Override
    public Integer release(Long id, String optFlag) throws CustomRuntimeException {
        AppRelease ar = appReleaseMapper.selectByPrimaryKey(id);
        if (null == ar) {
            throw new CustomRuntimeException(ErrorCode.RELEASE_NOT_EXISTS, ErrorCode.RELEASE_NOT_EXISTS.getMessage());
        }
        if (StringUtils.equals(ar.getReleaseStatus(), optFlag)) {
            throw new CustomRuntimeException(ErrorCode.RELEASE_DUPLICATE, ErrorCode.RELEASE_DUPLICATE.getMessage());
        }
        if (StringUtils.equals(optFlag, AppRelease.STATUS_SUCCESS)) {
            //TODO 只有一个记录发布状态，已发布的状态修改为初始化状态
            AppRelease arreq = new AppRelease();
            arreq.setReleaseStatus(AppRelease.STATUS_INIT);
            arreq.setSystemType(ar.getSystemType());
            appReleaseMapper.updateBySystemTypeAndStatus(arreq);
        }
        //update AppRelease
        ar.setUpdateTime(DateUtils.fullDateFormat());
        ar.setReleaseStatus(optFlag);
        appReleaseMapper.updateByPrimaryKeySelective(ar);

        RBucket<String> rb = redissonClient.getBucket(RedisConstant.APP_RELEASE + ar.getSystemType());
        if (StringUtils.equals(optFlag, AppRelease.STATUS_SUCCESS)) {
            Map<String, String> m = new HashMap<>();
            m.put(CommonConstant.PLATFORM_CODE, ar.getPlatformCode());
            m.put(CommonConstant.PLATFORM_VERSION, ar.getPlatformVersion());
            m.put(CommonConstant.VISIT_URL, ar.getVisitUrl());
            m.put(CommonConstant.MIX_VERSION, ar.getAppMinVersion());
            m.put(CommonConstant.MAX_VERSION, ar.getAppMaxVersion());
            m.put(CommonConstant.RELEASE_TYPE, ar.getReleaseType());
            m.put(CommonConstant.NOTE_FLAG, ar.getNoteFlag());
            m.put(CommonConstant.RELEASE_DES, ar.getReleaseDes());
            Gson g = new Gson();
            String str = g.toJson(m);
            log.info("set redis is :{}", str);
            rb.set(str, RedisConstant.APP_RELEASE_TIMEOUT, TimeUnit.HOURS);
        } else {
            rb.delete();
        }
        return 1;
    }

    @Override
    public ListAppReleaseResMsg listAppRelease(Integer pageSize, Integer pageNo) {
        ListAppReleaseResMsg ar = new ListAppReleaseResMsg();
        ar.setRecords(appReleaseMapper.listAppRelease(pageSize, pageNo));
        ar.setTotal(appReleaseMapper.listAppReleaseCount());
        return ar;
    }

    @Override
    public Integer saveAppRelease(AppReleaseReqMsg reqMsg) throws CustomRuntimeException, IOException {
        if (null != reqMsg.getId()) {
            AppRelease ar = new AppRelease();
            ar.setId(reqMsg.getId());
            ar.setUpdateTime(DateUtils.fullDateFormat());
            ar.setReleaseDes(reqMsg.getReleaseDes());
            return appReleaseMapper.updateByPrimaryKeySelective(ar);
        } else {
            AppRelease ar = BeanCopyUtils.beanCopy(reqMsg, AppRelease.class);
            String path = prefixPath + File.separator + ManagerConstant.PATH_APK + File.separator + RedisSerializableUtils.generateOrderNo(CommonConstant.DEFAULT_LENGTH) + "." + CommonConstant.DEFAULT_APK_PREFIX;
            CustomFileUtils.allFileBuild(path, Base64.getDecoder().decode(reqMsg.getFileData()));
            ar.setFullPkgUrl(path);
            ar.setVisitUrl(path.replace(prefixPath, visitUrl));
            ar.setReleaseStatus(AppRelease.STATUS_INIT);
            ar.setVersionType(AppRelease.VERSION_TYPE_FORMAL);
            ar.setId(Long.parseLong(RedisSerializableUtils.generateForLong(CommonConstant.DEFAULT_LENGTH)));
            ar.setCreateTime(DateUtils.fullDateFormat());
            ar.setUpdateTime(DateUtils.fullDateFormat());
            return appReleaseMapper.insertSelective(ar);
        }
    }

    @Override
    public AppRelease detail(Long id) {
        return null;
    }

    @Override
    public Integer delAppRelease(Long id) {
        return null;
    }
}
